package com.bidepan.spring6.aop.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

//切面类
@Component //ioc容器
/**
 * 切面优先级：
 * 相同目标方法上同时存在多个切面时，切面的优先级控制切面的 "内外嵌套" 顺序
 * 外：@Order(较小数)：优先级高
 * 内：@Order(较大数)：优先级低
 **/

public class LogAspect {
    //设置切入点和通知类型
    //通知类型: 前置 @Before(value = "切入点表达式)
    //         切入点表达式：execution(访问修饰符 增强方法返回类型 增强方法所在类全路径.方法名称(方法参数))
    //                                        *               *.*           *      ..
    //前置通知
    public void beforeMathod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("Logger-->前置通知|方法名称："+methodName+"，参数："+ Arrays.toString(args));
    }

    //返回通知
    public void afterReturningMethod(JoinPoint joinPoint,Object result){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("Logger-->返回通知|方法名称："+methodName+"，返回结果："+result);
    }

    //后置通知
    public void afterMathod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("Logger-->后置通知|方法名称："+methodName+"执行完毕...");
    }


    //异常通知
    public void afterThrowingMethod(JoinPoint joinPoint,Throwable ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("Logger-->异常通知|方法名称："+methodName+"，异常信息："+ex);
    }

    //环绕通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String argString = Arrays.toString(args);
        Object result = null;
        try{
            System.out.println("环绕通知==>目标方法之前执行");
            //调用目标方法（必须显式执行，一条龙服务不能少）
            result = joinPoint.proceed(args);
            System.out.println("环绕通知==>目标方法返回结果："+result);
            System.out.println("环绕通知==>目标方法已得到返回值");
        }catch (Throwable throwable){
            //输出异常信息
            throwable.printStackTrace();
            System.out.println("环绕通知==>目标方法出现异常！！");
        }finally {
             System.out.println("环绕通知==>目标方法执行完毕...");
        }
        return result;
    }

}
